eval 'exec perl -wS $0 ${1+"$@"}'
 if 0;

use strict;
use warnings;
use POSIX qw(strftime);

use DBI();
use File::Basename;
use File::stat;
use Data::Dumper 'Dumper';

# Following variable is used as a general file descriptor for all the 
# output of the current tool (the log file). Actually, this file will
# contain the copy of both the stdout and stderr channel.
my $G_LOG;

################################################################################
#
################################################################################
sub get_time
{
    my $separator=shift @_;
    my @timelist = @_;
    
    my $now_time="";
    
    if (! defined $separator)
    {
	$separator=":";
    }
    
    if (scalar @timelist<1)
    {
	@timelist=localtime();
    }
    
    $now_time = strftime("%H".$separator."%M".$separator."%S",@timelist);
    
    return $now_time;
}

################################################################################
#
################################################################################
sub get_date
{
    my $separator=shift @_;
    my @timelist = @_;
    
    my $now_date="";
    
    if (! defined $separator)
    {
	$separator="/";
    }
    
    if (scalar @timelist<1)
    {
	@timelist=localtime();
    }
    
    $now_date = POSIX::strftime("%Y".$separator."%m".$separator."%d",@timelist);
    
    return $now_date;
}

################################################################################
#
################################################################################
sub mylog
{
    if ($G_LOG)
    {
	print $G_LOG get_date()." ".get_time()." ".join("",@_);
    }
}

################################################################################
#
################################################################################
sub error
{
    print STDERR get_date()." ".get_time()." [ERROR] ",@_;
    mylog "[ERROR] ", @_;
}

################################################################################
#
################################################################################
sub warning
{
    print STDERR get_date()." ".get_time()." [WARNING] ",@_;
    mylog("[WARNING],",@_);
}

################################################################################
#
################################################################################
sub debug
{
    my $h_ref_param=shift @_;
    
    if (exists $h_ref_param->{DEBUG})
    {
	print STDOUT get_date()." ".get_time()." [DEBUG] ",@_;
	mylog("[DEBUG] ",@_);
    }
}

################################################################################
#
################################################################################
sub info
{
    print STDOUT get_date()." ".get_time()." [INFO] ",@_;
    mylog("[INFO] ",@_);
}


################################################################################
#
################################################################################
sub print_h_content
{
    my $h_ref_param=shift @_;
    
    debug $h_ref_param, "Printing Global Hash Content:\n";
    debug $h_ref_param, "######################################################\n";
    foreach my $thekey (keys %$h_ref_param)
    {
	debug $h_ref_param, $thekey." => ".$h_ref_param->{$thekey}."\n";
    }
    debug $h_ref_param, "######################################################\n";
}

################################################################################
#
################################################################################
sub db_connect
{
    my $h_ref_param=shift @_;

    my $dbh = DBI->connect("DBI:mysql:database=".$h_ref_param->{DBNAME}.";host=localhost",
                         $h_ref_param->{DBLOGIN}, $h_ref_param->{DBPASSWD},
                         {'RaiseError' => 0, 'AutoCommit' => 0});

    $h_ref_param->{DB}=$dbh;

    return (defined $dbh);
}

################################################################################
#
################################################################################
sub db_disconnect
{
    my $h_ref_param=shift @_;
    $h_ref_param->{DB}->disconnect();
}

################################################################################
#
################################################################################
sub db_get_id
{
    my $h_ref_param=shift @_;
    my $select_count = shift @_;
    my $select = shift @_;
    my $field = shift @_;
    my $res=0;
    my $sth;

    #print "SELECT_COUNT: " .$select_count. "\n";
    #print "SELECT: " .$select. "\n";

    $sth = $h_ref_param->{DB}->prepare("$select_count");
    $sth->execute();
    my $ref = $sth->fetchrow_hashref();
    
    $sth->finish();
    
    if ($ref->{'count(*)'} != 0)
    {
	$sth = $h_ref_param->{DB}->prepare("$select");
	$sth->execute();
	$ref = $sth->fetchrow_hashref();
    
	$sth->finish();
	#return $ref->{'event_id'};
	return $ref->{$field};
    }

    return $ref->{'count(*)'}!=0;
}

################################################################################
#
################################################################################
sub isLuhn
{
    my $number = shift @_;
    my($sum,$odd);

    foreach my $n (reverse split(//,$number)) {
#foreach my $n (split(//,$number)) {
        $odd=!$odd;
        if($odd) {
	    $sum+=$n;
        } else {
	    my $x=2*$n;
	    $sum+=$x>9?$x-9:$x;
        }
    }

    my $ok = 0+(($sum%10)==0);
    return $ok;
}

################################################################################
#
################################################################################
sub get_user_info
{
    my $h_ref_param=shift @_;
    #my $request_id=shift @_;
    my $request_id;
    my $select_count = shift @_;
    my $select = shift @_;
    my $res=0;
    my $sth;

    $sth = $h_ref_param->{DB}->prepare("$select_count");
    $sth->execute();
    my $ref = $sth->fetchrow_hashref();
    
    $sth->finish();
    
    if ($ref->{'count(*)'} != 0)
    {
	$sth = $h_ref_param->{DB}->prepare("$select");
	$sth->execute();
	$ref = $sth->fetchrow_hashref();
    
	$sth->finish();
	$h_ref_param->{USER_MAIL}=$ref->{'mail'};
	$h_ref_param->{USER_COMPANY}=$ref->{'company_id'};
	$h_ref_param->{USER_FILTER}=$ref->{'filter'};
	return $ref->{'login'};
    }

    return $ref->{'count(*)'}!=0;
}

################################################################################
#
################################################################################
sub db_get_list
{
    my $h_ref_param=shift @_;
    my $select=shift @_;
    my $res=0;
    my $sth;
    my $field="";
    my @list=();
    $field="imei";

    $sth = $h_ref_param->{DB}->prepare("$select");
    $sth->execute();

    while ( ($field) = $sth->fetchrow_array() ) 
    {
	$field=~s/\r\n$//;
	$field=~s/\n\r$//;
	$field=~s/\n$//;
	$field=~s/\r$//;
	push(@list,$field);
    }
    #warn Dumper [@ref];
    return @list;
}

################################################################################
#
################################################################################
sub db_update_request_status
{
    my $h_ref_param=shift @_;
    my $request=shift @_;
    my $sth;
    
    $sth = $h_ref_param->{DB}->prepare("update request set status='saved' where request_id='$request';");
    $sth->execute();

    return 1;
}

################################################################################
#
################################################################################
sub db_update_requested_imei_status
{
    my $h_ref_param=shift @_;
    my $request=shift @_;
    my $id=0;
    my $sth;
    my @content=();
    my $file="/tmp/".$request."_validate.txt";
    
    my $imei="";
    my $valid="";
    my $comment="";

    $request=~/.{8}1(.+)/;
    $id=$1;

    my $dbh = DBI->connect("DBI:mysql:database=simgen;host=localhost",
			   "root","Admin01ME!",
			   {'RaiseError' => 0, 'AutoCommit' => 0});
    
    open(FILE, "<$file");
    @content = <FILE>;

    foreach my $line (@content)
    {
	chomp($line);
	($imei,$valid,$comment)=split(";",$line);
	#print "-> ".$imei. " -> ".$valid. " -> ".$comment."\n";
        # update imei 
	$sth =$h_ref_param->{DB}->prepare("update requested_imei set status='$valid', comment='$comment' where request_id='$id' and imei='$imei';");
	$sth->execute();
    }

    return 1;
}

################################################################################
################################################################################
sub process
{ 
    my $h_ref_param=shift @_;
    my $err=0; my $res=0;
    my $alctac="";
    my $imei="";
    my $tacimei="";
    my $counter=0;
    my @taclist =();
    my @imeilist = ();
    my $errmsg="";
    my $event_id="";
    my $event_type_id="";
    my $event_type="";
    my $data="";
    my $client_id="";
    my $company_id="";
    my $request_owner="";
    my $request_id="";

    print_h_content($h_ref_param);
    
    if ( -f "/tmp/$h_ref_param->{REQUESTID}_validate.txt")
    {
	error("Result file $h_ref_param->{REQUESTID}_validate.txt already exists. Aborting... \n");
	return 1;
    }

    if ( ! -f $h_ref_param->{TACFILE})
    {
	error("Tac file $h_ref_param->{TACFILE} does not exist. Aborting... \n");
	return 1;
    }
    
    if (! db_connect($h_ref_param))
    {
	error("Failed to connect to database.\n");
	return 1;
    }

    info("Processing request $h_ref_param->{REQUESTID}... \n");
    if (! db_get_id($h_ref_param,"SELECT count(*) FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","SELECT * FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","request_id"))
    {
	error("REQUEST $h_ref_param->{REQUESTID} not found in DB. \n");
	return 1;
    }
    
    info("Getting request owner... \n");
    $request_owner = db_get_id($h_ref_param,"SELECT count(*) FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","SELECT * FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","owner");
    if ($request_owner eq 0)
    {
	error("REQUEST_OWNER not found in DB for request $h_ref_param->{REQUESTID}. \n");
	return 1;
    }
    debug $h_ref_param, "REQUEST_OWNER: " .$request_owner. "\n";
    
    info("Getting user info... \n");
    if (! get_user_info($h_ref_param,"SELECT count(*) FROM system_user WHERE login='$request_owner';","SELECT * FROM system_user WHERE login='$request_owner';"))
    {
	error("Failed to get user info.\n");
	return 1;
    }
     
    info("Getting request id from table request... \n");
    $request_id = db_get_id($h_ref_param,"SELECT count(*) FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","SELECT * FROM request WHERE request_id='$h_ref_param->{REQUESTID}';","id");
    if ($request_id eq 0)
    {
	error("REQUEST_ID not found in DB for request $h_ref_param->{REQUESTID}. \n");
	return 1;
    }

    info("Getting IMEI list... \n");
    @imeilist = db_get_list($h_ref_param,"select imei from requested_imei where request_id='$request_id' and owner='$request_owner' and status='new'");
    #warn Dumper [@imeilist];    

    if (scalar @imeilist == 0)
    {
	error "No imei found for request $h_ref_param->{REQUESTID}.  \n";
	return 1;
    } 	
    #info "Processing imei file $h_ref_param->{IMEIFILE}... \n";
    #open(IMEIFILE, "<$h_ref_param->{IMEIFILE}");
    #@imeilist = <IMEIFILE>;
    
    foreach $imei (@imeilist)
    {
	if ($imei eq "")
	{
	    next;
	}
	
	#info "Processing imei $imei... \n";
	
	#check format
	if ($imei!~/^(\d{15})$/)
	{
	    error("Bad format.\n");
	    `echo "$imei;no;Bad format;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
	    next;
	}
	#end check format
	
	#check checksum
	if (!isLuhn("$imei"))
	{
	    error("Bad checksum.\n");
	    `echo "$imei;no;Bad checksum;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
	    next;
	}
	#end check checksum
	
	#check tac
	
	$imei=~/^(\d{6})(\d{2})(\d{6})(\d{1})/;
	$tacimei=$1;
	
	open(TACFILE, "<$h_ref_param->{TACFILE}");
	@taclist = <TACFILE>;
	
	foreach $alctac (@taclist)
	{
	    chomp($alctac);    
	    if ($tacimei == $alctac)
	    {
		$counter++;
	    }
	}
	if ($counter == 0)
	{
	    #not a t&a mobile phone
	    error("Not a t&a mobile phone.\n");
	    `echo "$imei;no;Not a t&a mobile phone;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
	    next;
	}
	#end check tac
	
	#check imei owner
	$h_ref_param->{USER_FILTER}="DISABLED";
	if($h_ref_param->{USER_FILTER} eq "ENABLED")
	{
	    debug $h_ref_param,"Getting EVENT_ID... \n";
	    $event_id = db_get_id($h_ref_param,"SELECT count(*) FROM imei WHERE imei='$imei';","SELECT * FROM imei WHERE imei='$imei';","event_id");
	    if ($event_id == 0)
	    {
		error("EVENT_ID not found in DB for imei $imei. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "EVENT_ID: " .$event_id. "\n";
	    
	    debug $h_ref_param, "Getting EVENT_TYPE_ID... \n";
	    $event_type_id = db_get_id($h_ref_param,"SELECT count(*) FROM event WHERE id='$event_id';","SELECT * FROM event WHERE id='$event_id';","event_type_id");
	    if ($event_type_id == 0)
	    {
		error("EVENT_TYPE_ID not found in DB for event_id $event_id. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "EVENT_TYPE_ID: " .$event_type_id. "\n";
	    
	    debug $h_ref_param, "Getting DATA... \n";
	    $data = db_get_id($h_ref_param,"SELECT count(*) FROM event WHERE id='$event_id';","SELECT * FROM event WHERE id='$event_id';","data");
	    if ($data == 0)
	    {
		error("DATA not found in DB for event_id $event_id. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "DATA: " .$data. "\n";
	    
	    debug $h_ref_param, "Getting EVENT_TYPE... \n";
	    $event_type = db_get_id($h_ref_param,"SELECT count(*) FROM event_type WHERE id='$event_type_id';","SELECT * FROM event_type WHERE id='$event_type_id';","name");
	    if ($event_type eq 0)
	    {
		error("EVENT_TYPE not found in DB for event $event_type. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "EVENT_TYPE: " .$event_type. "\n";
	    
	    debug $h_ref_param, "Getting CLIENT_ID... \n";
	    $client_id = db_get_id($h_ref_param,"SELECT count(*) FROM $event_type WHERE id=$data;","SELECT * FROM $event_type WHERE id=$data;","client_id");
	    if ($client_id == 0)
	    {
		error("CLIENT_ID not found in DB for data $data. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "CLIENT_ID: " .$client_id. "\n";
	    
	    debug $h_ref_param, "Getting COMPANY_ID... \n";
	    $company_id = db_get_id($h_ref_param,"SELECT count(*) FROM client WHERE id=$client_id;","SELECT * FROM client WHERE id=$client_id;","company_id");
	    if ($company_id == 0)
	    {
		error("COMPANY_ID not found in DB for client_id $client_id. \n");
		`echo "$imei;no;Failed to determine the owner;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	    debug $h_ref_param, "COMPANY_ID: " .$company_id. "\n";
	    debug $h_ref_param, "USER_COMPANY : " .$h_ref_param->{USER_COMPANY}. "\n";
	    
	    if ($h_ref_param->{USER_COMPANY} ne $company_id)
	    {
		error("Not authorized to unlock phones for this operator.\n");
		`echo "$imei;no;Not authorized to unlock phones for this operator;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
		next;
	    }
	}
	#end check imei owner
	
	#imei is valid
	`echo "$imei;yes;;" >> /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
	    
    } #foreach $imei (@imeilist)

    info "Updating request status...\n";
    
    if (! db_update_request_status($h_ref_param,$h_ref_param->{REQUESTID}))
    {
	error "Failed to update request status.  \n";
	next;
    }
    
    # update requested imei status
    if (! db_update_requested_imei_status($h_ref_param,$h_ref_param->{REQUESTID}))
    {
	error "Failed to update requested imei status.  \n";
	next;
    }    

    # send mail with result
    #`cgi/sendmail.pl -f max.support\@tcl.com -t $h_ref_param->{USER_MAIL} -s "[ Request #: $h_ref_param->{REQUESTID} ] Max >validate_imei.pl< notification" /tmp/$h_ref_param->{REQUESTID}_validate.txt`;
    `cgi/sendmail.pl -f max.support\@tcl.com -t $h_ref_param->{USER_MAIL} -s "[ Request #: $h_ref_param->{REQUESTID} ]" <<EOF

Dear Client,

Your request $h_ref_param->{REQUESTID} has been taken into account.
You'll be informed by e-mail as soon as the treatment is achieved.

Best Regards,

Simlock Team

EOF`;
	
	info "End of Process. \n";

    if (! db_disconnect($h_ref_param))
    {
	warning("Failed to disconnect from database.\n");
    }
    
    return $err;
}

################################################################################
#
################################################################################
sub print_version
{
  my $h_ref_param=shift @_;
  print $h_ref_param->{EXECUTABLE_NAME}." ".$h_ref_param->{VERSION}." ".$h_ref_param->{RELEASE_DATE}."\n";
}

################################################################################
#
################################################################################
sub parse_args
{
    my $h_ref_param=shift @_;
    
    my $arg="";
    my $err=0;
    
    while ($arg=shift @ARGV)
    {
	chomp($arg);
	if ( $arg =~ /^-/ )
	{
	    if ( ($arg =~ /^-h/) || ($arg =~ /^--help/))
	    {
		print_usage($h_ref_param);
		exit(0);
	    }
	    elsif ( ($arg =~ /^-d/) || ($arg =~ /^--debug/))
	    {
		$h_ref_param->{DEBUG}=1;
	    }
	    elsif ( ($arg =~ /^-v/) || ($arg =~ /^--version/))
	    {
		print_version();
		exit(0);
	    }
	    
	    elsif ( ($arg =~ /^-l/) || ($arg =~ /^--log/))
	    {
		$arg=shift @ARGV;
		$h_ref_param->{LOG}=$arg;
	    }

	    else
	    {
		error "Unexpected option >$arg<.\n";
		$err++;
		next;
	    } 
	}
	else
	{
	     #<request id>: Mandatory. ID of request\n";
	    if (! exists $h_ref_param->{REQUESTID})
	    {
		$h_ref_param->{REQUESTID}=$arg;
	    }
	    #<tac file>: Mandatory. file containing list of tac. \n";
	    elsif (! exists $h_ref_param->{TACFILE})
	    {
		$h_ref_param->{TACFILE}=$arg;
	    }
	    #<dbname>: Mandatory. Local database name to use <dbname> database.\n";
	    elsif (! exists $h_ref_param->{DBNAME})
	    {
		$h_ref_param->{DBNAME}=$arg;
	    }
	    #<dblogin>: Mandatory. Local database login to use <dbname> database.\n";
	    elsif (! exists $h_ref_param->{DBLOGIN})
	    {
		$h_ref_param->{DBLOGIN}=$arg;
	    }
	    #<dbpasswd>: Mandatory. Local database password to use <dbname> database.\n";
	    elsif (! exists $h_ref_param->{DBPASSWD})
	    {
		$h_ref_param->{DBPASSWD}=$arg;
	    }
	}
    }
    
    if (! exists $h_ref_param->{DBPASSWD})
    {
	error("Missing arguments.\n");
	$err++;
    }
    
    if ($err>0)
    {
	error "Aborting due to previous error(s). Use -h or --help for usage.\n";
	return 1;
    }
    
    return 0;
}
    
################################################################################
#
################################################################################
sub print_usage
  {
    my $h_ref_param=shift @_;

    print "USAGE: ".$h_ref_param->{EXECUTABLE_NAME}." [-h|--help] [-d|--debug] [-v|--version] [-l|--log <log file>] ...] <request id> <imei file> <tac file> <dbname> <dblogin> <dbpasswd>\n";
    print "\n";
    print "PURPOSE:\n";
    print "   Validate IMEI \n";
    print "\n";
    print "PARAMETERS DESCRIPTION:\n";
    print "\n";
    print "   <request id>: Mandatory. ID of request.\n";
    print "\n";
    print "   <tacfile>: Mandatory. file comtaining alcatel tac.\n";
    print "\n";
    print "   <dbname>: Mandatory. Local database name to use <dbname> database.\n";
    print "\n";
    print "   <dblogin>: Mandatory. Local database login to use <dbname> database.\n";
    print "\n";
    print "   <dbpasswd>: Mandatory. Local database password to use <dbname> database.\n";
    print "\n";
    print "OPTIONS DESCRIPTION:\n";
    print "   [-h|--help]:\n";
    print "      Print this usage message and exit.\n";
    print "\n";
    print "   [-v|--version]:\n";
    print "      Print the version number and exit.\n";
    print "\n";
    print "   [-d|--debug]:\n";
    print "      Print excessive output to understand the processing.\n";
    print "\n";
    print "\n";
  }

################################################################################
#
################################################################################
sub open_log
{
    my $h_ref_param=shift @_;

    if (! open($G_LOG,">>".$h_ref_param->{LOG}))
    {
	warning "Cannot create log file ".$h_ref_param->{LOG}." in current directory.\n";

	$h_ref_param->{LOG}="/tmp/".$h_ref_param->{EXECUTABLE_NAME}.".log";

	if (! open($G_LOG,">".$h_ref_param->{LOG}))
	{
	    warning "Still cannot create alternative log file ".$h_ref_param->{LOG}.". No log will be performed.\n";
	    $G_LOG=0;
	}
    }
}


################################################################################
#
################################################################################
sub intro
  {
    my $h_ref_param=shift @_;
    my $err=0;
    my $date_for_file="";

    # Updating some global variables.

    $h_ref_param->{START_TIME}=get_date("-")." ".get_time(":");

    $date_for_file=get_date("-")."_".get_time("-");
    
    $h_ref_param->{VERSION}="0.3.2";
    $h_ref_param->{EXECUTABLE_NAME}="validate_imei.pl";

    $h_ref_param->{LOG}=$h_ref_param->{EXECUTABLE_NAME}.".$date_for_file.log";

    $h_ref_param->{LOCK_FILE}="/tmp/".$h_ref_param->{EXECUTABLE_NAME}.".lock";
    
    $h_ref_param->{RELEASE_DATE}="2007/10/17";

    # Following instruction forces flushing for each output to STDOUT or STDERR.
    $|=1;

    return 0;
  }

################################################################################
#
################################################################################
sub outtro
{
    my $h_ref_param=shift @_;
    if ($G_LOG)
    {
	close($G_LOG);
    }

    return 0;
}

################################################################################
#
################################################################################
sub main
{
  # This hash list will be used to store input parameters and some other
  # usefull information.
  # The actual valable keys are:
  #   VERSION:           string: current version of the tool.
  #   START_TIME:        string: start time of the script in the form YY_MM_DD.HH.MM.SS
  #   EXECUTABLE_NAME:   string: name of the current script.
  #   LOG:               string: name of the log file.
  #   RELEASE_DATE:      string: date of current tool release in form: YYYY/MM/DD
  #   DEBUG:             boolean: if this key exists, then the current script is run in
  #                               debug mode.
  #
  my %params=();
  my $res;
  
  if (intro(\%params)!=0)
  {
      error "Error while executing intro... Aborting.\n";
      exit(1);
  }

  if (parse_args(\%params)!=0)
  {
      error "Error while parsing arguments... Aborting.\n";
      exit(1);
  }
  
  #open_log(\%params);

  if (process(\%params)!=0)
  {
      error "Error while processing... Aborting.\n";
  }

  if (outtro(\%params)!=0)
  {
      error "Error while executing outtro... Aborting.\n";
      exit(1);
  }

}

################################################################################
#
################################################################################

main();
exit(0);

